package com.xudu.qdadabackend.service.impl;

import cn.hutool.core.util.ReUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.xudu.qdadabackend.common.ErrorCode;
import com.xudu.qdadabackend.constant.UserConstant;
import com.xudu.qdadabackend.exception.ServiceException;
import com.xudu.qdadabackend.model.dto.user.SearchUserRequest;
import com.xudu.qdadabackend.model.dto.user.UpdateUserRequest;
import com.xudu.qdadabackend.model.entity.User;
import com.xudu.qdadabackend.model.vo.UserVO;
import com.xudu.qdadabackend.service.UserService;
import com.xudu.qdadabackend.mapper.UserMapper;
import com.xudu.qdadabackend.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.xudu.qdadabackend.constant.UserConstant.ADMIN_ROLE;
import static com.xudu.qdadabackend.constant.UserConstant.USER_LOGIN_STATE;

/**
* @author xudu
* @description 针对表【user】的数据库操作Service实现
* @createDate 2024-10-10 22:53:56
*/
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService{

    @Resource
    private RedisUtil redisUtil;

    @Autowired
    private QiniuUtil qiniuUtil;

    @Override
    public Long RegisterUser(String userAccount, String userPassword, String checkPassword) throws Exception {
        //校验信息
        if (StringUtils.isAnyBlank(userAccount, userPassword, checkPassword)) {
            throw new ServiceException(ErrorCode.PARAMS_ERROR, "账号或密码为空");
        }
        if (userAccount.length() < 4) {
            throw new ServiceException(ErrorCode.PARAMS_ERROR, "账号过短");
        }
        if (userPassword.length() < 6 || checkPassword.length() < 6) {
            throw new ServiceException(ErrorCode.PARAMS_ERROR, "密码过短");
        }
        if (!checkPassword.equals(userPassword)) {
            throw new ServiceException(ErrorCode.PARAMS_ERROR, "两次密码不一致");
        }

        //校验账号是否包含特殊字符
        if (!ReUtil.contains("^[a-zA-Z0-9]{4,16}$", userAccount)) {
            throw new ServiceException(ErrorCode.PARAMS_ERROR, "账号不符合规范");
        }

        //校验账号是否重复
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(User::getUserAccount, userAccount);
        if (this.count(queryWrapper) > 0) {
            throw new ServiceException(ErrorCode.PARAMS_ERROR, "账号已存在");
        }

        //加密密码
        String encrypt = AESUtil.encrypt(userPassword);

        //保存用户
        User user = new User();
        user.setUserAccount(userAccount);
        user.setUserPassword(encrypt);
        this.save(user);

        //返回用户id
        return user.getId();
    }

    @Override
    public UserVO LoginUser(String userAccount, String userPassword) throws Exception {

        if (StringUtils.isAnyBlank(userAccount, userPassword)) {
            throw new ServiceException(ErrorCode.PARAMS_ERROR, "账号或密码为空");
        }
        if (userAccount.length() < 4) {
            throw new ServiceException(ErrorCode.PARAMS_ERROR, "账号过短");
        }
        if (userPassword.length() < 6) {
            throw new ServiceException(ErrorCode.PARAMS_ERROR, "密码过短");
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(User::getUserAccount, userAccount);
        User user = this.getOne(queryWrapper);
        if (user == null) {
            throw new ServiceException(ErrorCode.PARAMS_ERROR, "账号不存在");
        }
        if (!AESUtil.decrypt(user.getUserPassword()).equals(userPassword)) {
            throw new ServiceException(ErrorCode.PARAMS_ERROR, "密码错误");
        }

        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        String userTags = user.getUserTags();
        Gson gson = new Gson();
        List<String> userTagsList = gson.fromJson(userTags, new TypeToken<List<String>>() {
        }.getType());
        userVO.setUserTags(String.valueOf(userTagsList));

        //登录成功，记录用户登录态
        HttpServletRequest request = GetRequestUtil.getRequest();
        request.getSession().setAttribute(USER_LOGIN_STATE, userVO);

        //返回登陆用户脱敏后的信息
        return userVO;
    }

    @Override
    public Page<UserVO> getUserListByPage(SearchUserRequest searchUserRequest) {

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();

        //条件组合查询
        Long id = searchUserRequest.getId();
        if (id != null && id > 0) {
            queryWrapper.lambda().eq(User::getId, id);
        }
        String userAccount = searchUserRequest.getUserAccount();
        if (StringUtils.isNotBlank(userAccount)) {
            queryWrapper.lambda().like(User::getUserAccount, userAccount);
        }
        String userName = searchUserRequest.getUserName();
        if (StringUtils.isNotBlank(userName)) {
            queryWrapper.lambda().like(User::getUserName, userName);
        }
        String userPhone = searchUserRequest.getUserPhone();
        if (StringUtils.isNotBlank(userPhone)) {
            queryWrapper.lambda().like(User::getUserPhone, userPhone);
        }
        Integer userRole = searchUserRequest.getUserRole();
        if (userRole != null && userRole > 0) {
            queryWrapper.lambda().eq(User::getUserRole, userRole);
        }
        //todo 待添加用户标签查询
        String userTags = searchUserRequest.getUserTags();
        if (StringUtils.isNotBlank(userTags)) {
            queryWrapper.lambda().like(User::getUserTags, userTags);
        }
        int pageNum = searchUserRequest.getPageNum();
        int pageSize = searchUserRequest.getPageSize();

        Page<User> page = new Page<>(pageNum, pageSize);
        Page<User> userPage = this.page(page, queryWrapper);

        Page<UserVO> userVOPage = new Page<>(userPage.getCurrent(), userPage.getSize(), userPage.getTotal());
        ArrayList<UserVO> userVOList = new ArrayList<>();
        Gson gson = new Gson();
        userPage.getRecords().forEach(user -> {
            UserVO userVO = new UserVO();
            BeanUtils.copyProperties(user, userVO);
            String jsonUserTags = user.getUserTags();
            List<String> userTagsList = gson.fromJson(jsonUserTags, new TypeToken<List<String>>() {
            }.getType());
            userVO.setUserTags(String.valueOf(userTagsList));
            userVOList.add(userVO);
        });
        userVOPage.setRecords(userVOList);

        return userVOPage;
    }



    @Override
    public Boolean isAdmin() {
        HttpServletRequest request = GetRequestUtil.getRequest();

        Object userObj = request.getSession().getAttribute(USER_LOGIN_STATE);
        UserVO userVo = (UserVO) userObj;
        return userVo != null && Objects.equals(userVo.getUserRole(), ADMIN_ROLE);

    }

    @Override
    public Boolean isLogin() {
        HttpServletRequest request = GetRequestUtil.getRequest();

        Object userObj = request.getSession().getAttribute(USER_LOGIN_STATE);
        UserVO userVo = (UserVO) userObj;
        if (userVo == null){
            throw new ServiceException(ErrorCode.NOT_LOGIN_ERROR, "未登录");
        }
        return true;

    }

    @Override
    public UserVO getLoginUser() {
        HttpServletRequest request = GetRequestUtil.getRequest();

        Object userObj = request.getSession().getAttribute(USER_LOGIN_STATE);
        UserVO userVo = (UserVO) userObj;
        if (userVo == null){
            throw new ServiceException(ErrorCode.NOT_LOGIN_ERROR, "未登录");
        }
        return userVo;
    }

    @Override
    public Boolean updateUser(UpdateUserRequest updateUserRequest) {
        Long id = updateUserRequest.getId();
        if (id == null || id <= 0) {
            throw new ServiceException(ErrorCode.PARAMS_ERROR, "参数错误");
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(User::getId, id);
        User dbuser = this.getOne(queryWrapper);

        if (dbuser == null){
            throw new ServiceException(ErrorCode.PARAMS_ERROR, "用户不存在");
        }

        User user = new User();

        BeanUtils.copyProperties(updateUserRequest, user);

        List<String> userTags = updateUserRequest.getUserTags();
        Gson gson = new Gson();
        String jsonUserTags = gson.toJson(userTags);
        user.setUserTags(jsonUserTags);


        if (updateUserRequest.getUserImage()!=null){
            qiniuUtil.deleteFile(user.getUserImage());
            user.setUserImage(qiniuUtil.upload(updateUserRequest.getUserImage()));
        }
        return this.updateById(user);
    }

    @Override
    public Integer deleteUser(Long id) {
        //校验id是否合法
        if (id == null || id <= 0) {
            throw new ServiceException(ErrorCode.PARAMS_ERROR, "参数错误");
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(User::getId, id);
        User dbuser = this.getOne(queryWrapper);
        if (dbuser == null){
            throw new ServiceException(ErrorCode.PARAMS_ERROR, "用户不存在");
        }

        return this.baseMapper.deleteById(id);
    }

    @Override
    public Boolean banUser(Long id) {
        //校验id是否合法
        if (id == null || id <= 0) {
            throw new ServiceException(ErrorCode.PARAMS_ERROR, "参数为空");
        }

        User dbuser = this.getOne(new QueryWrapper<User>().lambda().eq(User::getId, id));
        if (dbuser == null){
            throw new ServiceException(ErrorCode.PARAMS_ERROR, id + "用户不存在");
        }
        User user = new User();
        user.setId(id);
        user.setUserRole(UserConstant.BAN_ROLE);
        return this.updateById(user);
    }

    @Override
    public UserVO getUserVO(User user) {
        if (user == null){
            return null;
        }
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        return userVO;
    }

    @Override
    public List<UserVO> getUserVO(List<User> userList) {
        if (CollectionUtils.isEmpty(userList)){
            return new ArrayList<>();
        }
        return userList.stream().map(this::getUserVO).collect(Collectors.toList());
    }
}




